/**
 * 
 */
package v1c08;

import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

import javax.swing.JComponent;
import javax.swing.JFrame;

/**
 * @author gjunming@gmail.com
 * @version Aug 7, 2009 4:28:59 PM
 */
public class MouseEventTest {

	protected static final int FWIDTH = 300;
	protected static final int FHEIGHT = 200;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				JFrame mouseFrame = new JFrame();
				mouseFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				mouseFrame.setSize(FWIDTH, FHEIGHT);
				mouseFrame.setVisible(true);

				MouseComponent mouseComponent = new MouseComponent();
				mouseFrame.add(mouseComponent);
			}
		});
	}
}

class MouseComponent extends JComponent {

	private static final long serialVersionUID = 1L;
	private final ArrayList<Rectangle2D> rects;
	private Rectangle2D current;
	public static final int RECT_LENGTH = 10;

	public MouseComponent() {
		rects = new ArrayList<Rectangle2D>();
		current = null;

		addMouseListener(new MyMouseListener());
		addMouseMotionListener(new MyMouseMotionListener());
	}

	@Override
	public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		for (Rectangle2D rect : rects) {
			g2.draw(rect);
		}
	}

	public void addRect(Point2D p) {
		double x = p.getX();
		double y = p.getY();

		current = new Rectangle2D.Double(x - RECT_LENGTH / 2, y - RECT_LENGTH
				/ 2, RECT_LENGTH, RECT_LENGTH);
		rects.add(current);
		repaint();
	}

	public void removeRect(Rectangle2D s) {
		if (s == null) {
			return;
		} else if (s == current) {
			current = null;
		}
		rects.remove(s);
		repaint();
	}

	public Rectangle2D findRect(Point2D p) {
		for (Rectangle2D rect : rects) {
			if (rect.contains(p)) {
				return rect;
			}
		}
		return null;
	}

	private class MyMouseListener extends MouseAdapter {
		@Override
		public void mousePressed(MouseEvent e) {
			current = findRect(e.getPoint());
			if (current == null) {
				addRect(e.getPoint());
			}
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			current = findRect(e.getPoint());
			if (e.getClickCount() == 2) {
				removeRect(current);
			}
		}
	}

	private class MyMouseMotionListener implements MouseMotionListener {

		/*
		 * @see
		 * java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent
		 * )
		 */
		@Override
		public void mouseDragged(MouseEvent e) {
			if (current != null) {
				double x = e.getX();
				double y = e.getY();

				current.setFrame(x - RECT_LENGTH / 2, y - RECT_LENGTH / 2,
						RECT_LENGTH, RECT_LENGTH);
				repaint();
			}
		}

		/*
		 * @see
		 * java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent
		 * )
		 */
		@Override
		public void mouseMoved(MouseEvent e) {
			if (findRect(e.getPoint()) == null) {
				setCursor(Cursor.getDefaultCursor());
			} else {
				setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
			}
		}
	}
}
